home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianMenus.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  25KB  |  1,087 lines

  1. /*ScianMenus.c
  2.   Eric Pepke
  3.   August 8, 1992
  4.  
  5.   Handles menus for SciAn
  6. */
  7.  
  8. #include "Scian.h"
  9. #include "ScianTypes.h"
  10. #include "ScianWindows.h"
  11. #include "ScianLists.h"
  12. #include "ScianColors.h"
  13. #include "ScianErrors.h"
  14. #include "ScianIDs.h"
  15. #include "ScianEvents.h"
  16. #include "ScianDatasets.h"
  17. #include "ScianHelp.h"
  18. #include "ScianArrays.h"
  19. #include "ScianFiles.h"
  20. #include "ScianFontSystem.h"
  21. #include "ScianDraw.h"
  22. #include "ScianObjFunctions.h"
  23. #include "ScianGlobalFunctions.h"
  24. #include "ScianStyle.h"
  25. #include "ScianErrors.h"
  26. #include "ScianRecorders.h"
  27. #include "ScianAnimation.h"
  28. #include "ScianSymbols.h"
  29. #include "ScianDatabase.h"
  30. #include "ScianMenus.h"
  31. #include "ScianTextBoxes.h"
  32.  
  33. ObjPtr menuClass;        /*Class of menus*/
  34. ObjPtr actionClass;        /*Class of actions*/
  35. ObjPtr textSizeActionClass;    /*Class of text size actions*/
  36.  
  37. ObjPtr mainMenu;        /*Main menu*/
  38. ObjPtr fileMenu;        /*File menu*/
  39. ObjPtr datasetsMenu;        /*Datasets menu*/
  40. ObjPtr objectMenu;        /*Object menu*/
  41. ObjPtr arrangeMenu;        /*Arrange menu*/
  42. ObjPtr networkMenu;        /*Network menu*/
  43. ObjPtr deusMenu;        /*Deus menu*/
  44. ObjPtr windowMenu;        /*Window menu*/
  45. ObjPtr animationMenu;        /*Animation menu*/
  46. ObjPtr locationMenu;        /*Window location menu*/
  47. ObjPtr tileMenu;        /*Tile menu*/
  48. ObjPtr textMenu;        /*Text menu*/
  49. ObjPtr fontSizeMenu;        /*Text size submenu*/
  50. ObjPtr alignMenu;        /*Text alignment submenu*/
  51. ObjPtr fontMenu;        /*Font submenu*/
  52. ObjPtr colorMenu;        /*Color submenu*/
  53. ObjPtr colorModelMenu;        /*Color model submenu*/
  54. ObjPtr hiddenMenu;        /*Hidden menu, for random things.*/
  55.  
  56. #ifdef MENUS4D
  57. static int nStoredActions = 0;        /*Number of stored actions for old routines*/
  58. static ObjPtr *storedActions = 0;
  59. static int nStoredActionsAllocated = 0;    /*Number of stored items allocated*/
  60. #endif
  61.  
  62. static ObjPtr keyActions[MAX_KEYS][4];
  63.  
  64. #ifdef PROTO
  65. ObjPtr NewMenu(char *name)
  66. #else
  67. ObjPtr NewMenu(name)
  68. char *name;
  69. #endif
  70. /*Makes a new menu with name*/
  71. {
  72.     ObjPtr retVal;
  73.  
  74.     retVal = NewObject(menuClass, 0L);
  75.     if (retVal)
  76.     {
  77.     SetVar(retVal, NAME, NewString(name));
  78.     }
  79.  
  80.     return retVal;
  81. }
  82.  
  83. #ifdef PROTO
  84. void AddMenuItem(ObjPtr menu, ObjPtr item, int group)
  85. #else
  86. void AddMenuItem(menu, item, group)
  87. ObjPtr menu;
  88. ObjPtr item;
  89. int group;
  90. #endif
  91. /*Adds item to menu.  Group is the menu item group*/
  92. {
  93.     ObjPtr items;
  94.     ObjPtr var;
  95.     ObjPtr *elements;
  96.     long dim;
  97.  
  98.     SetVar(item, ITEMGROUP, NewInt(group));
  99.  
  100.     items = GetVar(menu, ITEMS);
  101.     if (!items)
  102.     {
  103.     dim = 1;
  104.     items = NewArray(AT_OBJECT, 1, &dim);
  105.     elements = ELEMENTS(items);
  106.     elements[0] = item;
  107.     }
  108.     else
  109.     {
  110.     elements = ELEMENTS(items);
  111.     for (dim = 0; dim < DIMS(items)[0]; ++dim)
  112.     {
  113.         var = GetVar(elements[dim], ITEMGROUP);
  114.         if (var)
  115.         {
  116.         if (GetInt(var) > group) break;
  117.         }
  118.     }
  119.     items = InsertInArray(items, item, dim);
  120.     }
  121.     SetVar(menu, ITEMS, items);
  122.     SetVar(item, PARENT, menu);
  123. }
  124.  
  125. #ifdef PROTO
  126. ObjPtr NewAction(char *name, ObjPtr class)
  127. #else
  128. ObjPtr NewAction(name, class)
  129. char *name;
  130. ObjPtr class;
  131. #endif
  132. /*Returns a new action*/
  133. {
  134.     ObjPtr retVal;
  135.  
  136.     retVal = NewObject(class ? class : actionClass, 0L);
  137.     if (name)
  138.     {
  139.     SetVar(retVal, NAME, NewString(name));
  140.     }
  141. #ifdef MENUS4D
  142.     if (nStoredActions >= nStoredActionsAllocated)
  143.     {
  144.         if (nStoredActionsAllocated)
  145.         {
  146.         nStoredActionsAllocated += 100;
  147.         storedActions = Realloc(storedActions, nStoredActionsAllocated * sizeof(ObjPtr));
  148.         }
  149.         else
  150.         {
  151.         nStoredActionsAllocated = 100;
  152.         storedActions = Alloc(nStoredActionsAllocated * sizeof(ObjPtr));
  153.         }
  154.     }
  155.  
  156.     {
  157.         /*Allocate a menu helper*/
  158.         storedActions[nStoredActions] = retVal;
  159.         SetVar(retVal, STOREDACTION, NewInt(nStoredActions));
  160.         ++nStoredActions;
  161.     }
  162. #endif
  163.     return retVal;
  164. }
  165.  
  166. #ifdef PROTO
  167. ObjPtr NewSimpleAction(char *name, FuncTyp action)
  168. #else
  169. ObjPtr NewSimpleAction(name, action)
  170. char *name;
  171. FuncTyp action;
  172. #endif
  173. /*Makes a new simple action*/
  174. {
  175.     ObjPtr retVal;
  176.  
  177.     retVal = NewAction(name, actionClass);
  178.     if (retVal)
  179.     {
  180.     SetMethod(retVal, ACTIONMETHOD, action);
  181.     }
  182.  
  183.     return retVal;
  184. }
  185.  
  186. #ifdef MENUS4D
  187. void ActionHelper(n)
  188. long n;
  189. /*Helper for actions on a GL menu*/
  190. {
  191.     ObjPtr action;
  192.     FuncTyp method;
  193.  
  194.     action = storedActions[n];
  195.     if (!action)
  196.     {
  197.     ReportError("ActionHelper", "No stored action");
  198.     }
  199.  
  200.     method = GetMethod(action, ACTIONMETHOD);
  201.     if (method)
  202.     {
  203.     (*method)(action);
  204.     }
  205. }
  206.  
  207. ObjPtr MakeGLMenuStructure(menu)
  208. ObjPtr menu;
  209. /*Makes a menu structure for a GL menu*/
  210. {
  211.     ObjPtr items;
  212.     ThingListPtr runner;
  213.     ObjPtr var, item;
  214.     long pup;
  215.     int storedAction, nextStoredAction;
  216.     char *name;
  217.  
  218.     /*Get rid of old menu*/
  219.     var = GetVar(menu, MENUSTRUCTURE);
  220.     if (var)
  221.     {
  222.     freepup((long) GetInt(var));
  223.     SetVar(menu, MENUSTRUCTURE, NULLOBJ);
  224.     }
  225.  
  226.     MakeVar(menu, NAME);
  227.     var = GetVar(menu, NAME);
  228.     pup = newpup();
  229.     if (GetPredicate(menu, HASTITLE))
  230.     {
  231.     sprintf(tempStr, "%%t%s", var ? GetString(var) : "??");
  232.     addtopup(pup, tempStr);
  233.     }
  234.  
  235.     items = GetVar(menu, ITEMS);
  236.     if (items)
  237.     {
  238.     ObjPtr *elements;
  239.     long k;
  240.     long curGroup = 0;
  241.     Bool withLine = false;
  242.  
  243.     elements = ELEMENTS(items);
  244.  
  245.     var = GetVar(elements[0], ITEMGROUP);
  246.     if (var)
  247.     {
  248.         curGroup = GetInt(var);
  249.     }
  250.  
  251.     for (k = 0; k < DIMS(items)[0]; ++k)
  252.     {
  253.         item = elements[k];
  254.         var = GetVar(item, CLASSID);
  255.  
  256.         if (var && (GetInt(var) == CLASS_ACTION))
  257.         {
  258.         char *s;
  259.  
  260.         /*It's an action.  Put it in the menu*/
  261.         var = GetIntVar("MakeGLMenuStructure", item, STOREDACTION);
  262.         if (!var) continue;
  263.         storedAction = GetInt(var);
  264.  
  265.         MakeVar(item, NAME);
  266.         var = GetStringVar("MakeGLMenuStructure", item, NAME);
  267.         if (!var) continue;
  268.         name = GetString(var);
  269.  
  270.         withLine = false;
  271.  
  272.         if (k < DIMS(items)[0] - 1)
  273.         {
  274.             var = GetVar(elements[k + 1], ITEMGROUP);
  275.             if (var && GetInt(var) > curGroup)
  276.             {
  277.             withLine = true;
  278.             curGroup = GetInt(var);
  279.             }
  280.         }
  281.  
  282.         s = tempStr;
  283.         strcpy(s, name);
  284.         while (*s) ++s;
  285.         if (withLine)
  286.         {
  287.             strcpy(s, "%l");
  288.         }
  289.         while (*s) ++s;
  290.         var = GetVar(item, FUNCTIONKEY);
  291.         if (var)
  292.         {
  293.             int fk, flags;
  294.             fk = GetInt(var);
  295.             var = GetVar(item, FUNCTIONFLAGS);
  296.             if (var)
  297.             {
  298.             flags = GetInt(var) & 3;
  299.             }
  300.             else
  301.             {
  302.             flags = 0;
  303.             }
  304.             strcpy(s, " [");
  305.             ++s;
  306.             ++s;
  307.             switch (flags)
  308.             {
  309.             case F_SHIFTDOWN:
  310.                 strcpy(s, "Shift-");
  311.                 break;
  312.             case F_OPTIONDOWN:
  313.                 strcpy(s, "Alt-");
  314.                 break;
  315.             case F_SHIFTDOWN + F_OPTIONDOWN:
  316.                 strcpy(s, "Shift-Alt-");
  317.                 break;
  318.             }
  319.             while (*s) ++s;
  320.  
  321.             if (fk < 256)
  322.             {
  323.             sprintf(s, "%c", fk);
  324.             }
  325.             else if (fk >= FK_BASE)
  326.             {
  327.             sprintf(s, "%s", functionKeyNames[fk - FK_BASE] ? functionKeyNames[fk - FK_BASE] : "?");
  328.             }
  329.             else
  330.             {
  331.             strcpy(s, "?");
  332.             }
  333.             while (*s) ++s;
  334.             strcpy(s, "]");
  335.             ++s;
  336.         }
  337.  
  338.         sprintf(s, "%%x%d", storedAction);
  339.         while (*s) ++s;
  340.         strcpy(s, "%f");
  341.         addtopup(pup, tempStr, ActionHelper);
  342.         }
  343.         else if (var && (GetInt(var) == CLASS_MENU))
  344.         {
  345.         /*It's a menu.  Make it.*/
  346.         long subMenu;
  347.  
  348.         MakeVar(item, MENUSTRUCTURE);
  349.         var = GetVar(item, MENUSTRUCTURE);
  350.         if (!var) continue;
  351.         subMenu = (long) GetInt(var);
  352.  
  353.         MakeVar(item, NAME);
  354.         var = GetStringVar("MakeGLMenuStructure", item, NAME);
  355.         if (!var) continue;
  356.         name = GetString(var);
  357.  
  358.         withLine = false;
  359.  
  360.         if (k < DIMS(items)[0] - 1)
  361.         {
  362.             var = GetVar(elements[k + 1], ITEMGROUP);
  363.             if (var && GetInt(var) > curGroup)
  364.             {
  365.             withLine = true;
  366.             curGroup = GetInt(var);
  367.             }
  368.         }
  369.  
  370.         if (withLine)
  371.         {
  372.             sprintf(tempStr, "%s%%l%%m", name);
  373.         }
  374.         else
  375.         {
  376.             sprintf(tempStr, "%s%%m", name);
  377.         }
  378.         addtopup(pup, tempStr, subMenu);
  379.         }
  380.         else
  381.         {
  382.         ReportError("MakeGLMenuStructure", "Bad menu item");
  383.         }
  384.     }
  385.     }
  386.  
  387.     SetVar(menu, MENUSTRUCTURE, NewInt((int) pup));
  388. }
  389.  
  390. ObjPtr CleanupGLMenuStructure(menu)
  391. ObjPtr menu;
  392. /*Cleans up the GL menu structure*/
  393. {
  394.     ObjPtr var;
  395.  
  396.     var = GetVar(menu, MENUSTRUCTURE);
  397.     if (var)
  398.     {
  399.     freepup((long) GetInt(var));
  400.     }
  401.     return ObjTrue;
  402. }
  403. #endif
  404.  
  405. #ifdef PROTO
  406. void ChooseMenuActivation(ObjPtr menu)
  407. #else
  408. void ChooseMenuActivation(menu)
  409. ObjPtr menu;
  410. #endif
  411. /*Chooses whether items in a menu are activated or not*/
  412. {
  413.     ObjPtr *elements;
  414.     ObjPtr var;
  415.     long k;
  416.     long dim;
  417.     Bool anyActivated = false;
  418.  
  419. #ifdef MENUS4D
  420.     long menuStructure = 0;
  421.  
  422.     var = GetVar(menu, MENUSTRUCTURE);
  423.     if (var) menuStructure = GetInt(var);
  424. #endif
  425.  
  426.     if (GetMethod(menu, ACTIVATED))
  427.     {
  428.     MakeVar(menu, ACTIVATED);
  429.     }
  430.     else
  431.     {
  432.     var = GetVar(menu, ITEMS);
  433.     if (var)
  434.     {
  435.     Bool thisActivated;
  436.  
  437.     elements = ELEMENTS(var);
  438.     dim = DIMS(var)[0];
  439.  
  440.     for (k = 0; k < dim; ++k)
  441.     {
  442.         var = GetVar(elements[k], CLASSID);
  443.         if (var && GetInt(var) == CLASS_MENU)
  444.         {
  445.         /*Activate all the items on this menu*/
  446.         ChooseMenuActivation(elements[k]);
  447.         }
  448.         SetVar(elements[k], READYTOACTIVATE, ObjTrue);
  449.         MakeVar(elements[k], ACTIVATED);
  450.         thisActivated = GetPredicate(elements[k], ACTIVATED);
  451.         if (thisActivated) anyActivated = true;
  452.  
  453. #ifdef MENUS4D
  454. #ifdef PUP_GREY
  455. #ifdef PUP_NONE
  456.         if (menuStructure)
  457.         setpup(menuStructure, k
  458. #ifndef MENUSFROM0
  459.  + 1
  460. #endif
  461.         , thisActivated || contextHelp ? PUP_NONE : PUP_GREY);
  462. #endif
  463. #endif
  464. #endif
  465.     }
  466.     }
  467.     SetVar(menu, ACTIVATED, anyActivated ? ObjTrue : ObjFalse);
  468.     }
  469. }
  470.  
  471.  
  472. #ifdef PROTO
  473. void DrawFSOverMenu(ObjPtr menu, int x, int y)
  474. #else
  475. void DrawFSOverMenu(menu, x, y)
  476. #endif
  477. /*Draws an overlay menu, full screen*/
  478. {
  479.     int l, r, b, t;
  480.     int width, height, w;
  481.     int nItems;
  482.     ObjPtr *items;
  483.     ObjPtr var;
  484.     int k;
  485.     int group;
  486.  
  487.     /*Get the menu's items*/
  488.     MakeVar(menu, ITEMS);
  489.     var = GetVar(menu, ITEMS);
  490.     if (!var)
  491.     {
  492.     return;
  493.     }
  494.     nItems = DIMS(var)[0];
  495.     items = ELEMENTS(var);
  496.  
  497.     /*Find size of menu*/
  498.     height = nItems * (MENUFONTSIZE + MENUTBORDER + MENUBBORDER);
  499.     width = 0;
  500.     for (k = 0; k < nItems; ++k)
  501.     {
  502.     MakeVar(items[k], NAME);
  503.     var = GetVar(items[k], NAME);
  504.     if (var)
  505.     {
  506.         w = StrWidth(GetString(var));
  507.         if (w > width) width = w;
  508.         
  509.     }
  510.     }
  511.     /*Put in space for left and right borders*/
  512.     width += MENULBORDER + MENURBORDER;
  513.  
  514.     if (x + width > scrWidth)
  515.     {
  516.     x = scrWidth - width;
  517.     }
  518.     if (y - height < 0)
  519.     {
  520.     y = height;
  521.     }
  522.  
  523.     /*Make the back of the menu*/
  524.     FillUIRect(x, x + width + 1, y - height, y + 1, UIOVERGRAY);
  525.     FillUIGauzeRect(x, x + width + 1, y - height, y + 1, UIOVERWHITE);
  526.  
  527.     /*Make the border around the menu*/
  528.     /* bottom */
  529.     SetUIColor(UIOVERGRAY);
  530.     FillIntQuad(x + 1, y + 1 - height,
  531.         x + 1 - MENUEDGE, y + 1 - height - MENUEDGE,
  532.         x + 1 + width + MENUEDGE, y + 1 - height - MENUEDGE,
  533.         x + 1 + width, y + 1 - height);
  534.  
  535.     /* left */
  536.     SetUIColor(UIOVERWHITE);
  537.     FillIntQuad(x + 1, y + 1,
  538.         x + 1 - MENUEDGE, y + 1 + MENUEDGE,
  539.         x + 1 - MENUEDGE, y + 1 - height - MENUEDGE,
  540.         x + 1, y + 1 - height);
  541.  
  542.     /* right */
  543.     SetUIColor(UIOVERGRAY);
  544.     FillIntQuad(x + 1 + width, y + 1,
  545.         x + 1 + width, y + 1 - height,
  546.         x + 1 + width + MENUEDGE, y + 1 - height - MENUEDGE,
  547.         x + 1 + width + MENUEDGE, y + 1 + MENUEDGE);
  548.  
  549.     /* top */
  550.     SetUIColor(UIOVERWHITE);
  551.     FillIntQuad(x + 1 - MENUEDGE, y + 1+ MENUEDGE,
  552.         x + 1, y + 1,
  553.         x + 1 + width, y + 1,
  554.         x + 1 + width + MENUEDGE, y + 1 + MENUEDGE);
  555.  
  556.     FrameUIRect(x - MENUEDGE - 1, x + 1 + width + MENUEDGE, 
  557.         y - height - MENUEDGE - 1, y + 1 + MENUEDGE,
  558.         UIOVERBLACK);
  559.  
  560.     /*Draw the names*/
  561.     for (k = 0; k < nItems; ++k)
  562.     {
  563.     var = GetVar(items[k], NAME);
  564.     if (var)
  565.     {
  566.         MakeVar(items[k], ACTIVATED);
  567.         SetUIColor(GetPredicate(items[k], ACTIVATED) ? UIOVERBLACK : UIOVERGRAY);
  568.         DrawAString(LEFTALIGN, x + MENULBORDER,
  569.         y - k * (MENUFONTSIZE + MENUTBORDER + MENUBBORDER) - MENUTBORDER - MENUFONTSIZE,
  570.         GetString(var));
  571.     }
  572.     }
  573.  
  574.     /*Draw the groups*/
  575.     group = 0;
  576.  
  577.     for (k = 0; k < nItems; ++k)
  578.     {
  579.     var = GetVar(items[k], ITEMGROUP);
  580.     if (var)
  581.     {
  582.         if (GetInt(var) > group)
  583.         {
  584.         group = GetInt(var);
  585.         DrawUILine(x, y - (k - 1) * (MENUTBORDER + MENUFONTSIZE + MENUBBORDER),
  586.                x + width - 1, y - (k - 1) * (MENUTBORDER + MENUFONTSIZE + MENUBBORDER),
  587.                UIOVERGRAY);
  588.         DrawUILine(x, y - 1 - (k - 1) * (MENUTBORDER + MENUFONTSIZE + MENUBBORDER),
  589.                x + width - 1, y - 1 - (k - 1) * (MENUTBORDER + MENUFONTSIZE + MENUBBORDER),
  590.                UIOVERWHITE);
  591.         }
  592.     }
  593.     }
  594. }
  595.  
  596.  
  597. #ifdef PROTO
  598. void DoMenu(ObjPtr menu, int x, int y)
  599. #else
  600. void DoMenu(menu, x, y)
  601. ObjPtr menu;
  602. int x, y;
  603. #endif
  604. /*Does menu in menu, with beginning point in x and y*/
  605. {
  606. #ifdef MENUSGLOVER
  607.     int newX, newY;
  608. #endif
  609. #ifdef MENUS4D
  610.     ObjPtr var;
  611.     long pup;
  612. #endif
  613.  
  614. #ifdef MENUSGLOVER
  615.     if (nOverDrawPlanes >= 2)
  616.     {
  617.     ChooseMenuActivation(menu);
  618.     FullScreen(true);
  619.     OverDrawMenus(true);
  620.     SetUIFont(UIMENUFONT);
  621.     DrawFSOverMenu(menu, x, y);
  622.     while (Mouse(&newX, &newY));
  623.     SetUIColor(UIOVERCLEAR);
  624.     EraseAll();
  625.     OverDrawMenus(false);
  626.     FullScreen(false);
  627.     return;
  628.     }
  629. #endif
  630.  
  631. #ifdef MENUS4D
  632.     MakeVar(menu, MENUSTRUCTURE);
  633.     ChooseMenuActivation(menu);
  634.     var = GetIntVar("DoMenu", menu, MENUSTRUCTURE);
  635.     if (var)
  636.     {
  637.     dopup((long) GetInt(var));
  638.     return;
  639.     }
  640. #endif
  641. }
  642.  
  643. static ObjPtr MakeFontSizeActivated(menu)
  644. ObjPtr menu;
  645. /*Makes the font size menu activated or not*/
  646. {
  647.     ObjPtr allSelected;
  648.     ThingListPtr runner;
  649.     ObjPtr var;
  650.  
  651.     var = GetStringVar("MakeFontSizeActivated", menu, NAME);
  652.     if (!var) return ObjFalse;
  653.  
  654.     allSelected = GetListVar("MakeFontSizeActivated", menu, ALLSELECTED);
  655.     if (allSelected)
  656.     {
  657.     for (runner = LISTOF(allSelected); runner; runner = runner -> next)
  658.     {
  659.         if (GetMethod(runner -> thing, SETTEXTSIZE))
  660.         {
  661.         SetVar(menu, ACTIVATED, ObjTrue);
  662.         return ObjTrue;
  663.         } 
  664.     }
  665.     }
  666.     SetVar(menu, ACTIVATED, ObjFalse);
  667.     return ObjTrue;
  668. }
  669.  
  670. static ObjPtr MakeFontActivated(menu)
  671. ObjPtr menu;
  672. /*Makes the font menu activated or not*/
  673. {
  674.     ObjPtr allSelected;
  675.     ThingListPtr runner;
  676.     ObjPtr var;
  677.  
  678.     var = GetStringVar("MakeFontSizeActivated", menu, NAME);
  679.     if (!var) return ObjFalse;
  680.  
  681.     allSelected = GetListVar("MakeFontSizeActivated", menu, ALLSELECTED);
  682.     if (allSelected)
  683.     {
  684.     for (runner = LISTOF(allSelected); runner; runner = runner -> next)
  685.     {
  686.         if (GetMethod(runner -> thing, SETTEXTFONT))
  687.         {
  688.         SetVar(menu, ACTIVATED, ObjTrue);
  689.         return ObjTrue;
  690.         } 
  691.     }
  692.     }
  693.     SetVar(menu, ACTIVATED, ObjFalse);
  694.     return ObjTrue;
  695. }
  696.  
  697. #ifdef PROTO
  698. void SpitOutMenu(ObjPtr menu, int level)
  699. #else
  700. void SpitOutMenu(menu, level)
  701. ObjPtr menu;
  702. int level;
  703. #endif
  704. /*Spits out a menu at level*/
  705. {
  706.     ObjPtr *items;
  707.     ObjPtr item;
  708.     int nItems, k;
  709.     char *help, name[200];
  710.     char modHelp[1000];
  711.     char *s, *d;
  712.     ObjPtr var;
  713.     
  714.     MakeVar(menu, ITEMS);
  715.     var = GetVar(menu, ITEMS);
  716.     items = ELEMENTS(var);
  717.     nItems = DIMS(var)[0];
  718.  
  719.     for (k = 0; k < nItems; ++k)
  720.     {
  721.     item = items[k];
  722.  
  723.     var = GetVar(item, CLASSID);
  724.     if (var && GetInt(var) == CLASS_MENU)
  725.     {
  726.         if (!GetPredicate(item, HALTAUTODOC))
  727.         {
  728.         MakeVar(item, NAME);
  729.         var = GetVar(item, NAME);
  730.         if (level < 2)
  731.         {
  732.            printf("The %s menu\n", GetString(var));
  733.         }
  734.         }
  735.     }
  736.  
  737.     MakeVar(item, NAME);
  738.     var = GetStringVar("SpitOutMenu", item, NAME);
  739.     strcpy(name, GetString(var));
  740.     d = name;
  741.     while (*d) ++d;
  742.     --d;
  743.     while (*d == '.') --d;
  744.     ++d;
  745.     *d = 0;
  746.  
  747.     var = GetVar(item, HELPSTRING);
  748.     if (!var)
  749.     {
  750.         printf("WARNING!  No HELPSTRING on %s\n", name);
  751.         continue;
  752.     }
  753.     help = GetString(var);
  754.  
  755.     if (strstr(help, "Choosing this menu item"))
  756.     {
  757.         s = help + strlen("Choosing this menu item");
  758.         sprintf(modHelp, "The %s item", name);
  759.         d = modHelp;
  760.         while (*d) ++d;
  761.         strcpy(d, s);
  762.     }
  763.     else if (strstr(help, "Choosing this item"))
  764.     {
  765.         s = help + strlen("Choosing this item");
  766.         sprintf(modHelp, "The %s item", name);
  767.         d = modHelp;
  768.         while (*d) ++d;
  769.         strcpy(d, s);
  770.     }
  771.     else if (strstr(help, "This menu"))
  772.     {
  773.         s = help + strlen("This menu");
  774.         sprintf(modHelp, "The %s menu", name);
  775.         d = modHelp;
  776.         while (*d) ++d;
  777.         strcpy(d, s);
  778.     }
  779.     else strcpy(modHelp, help);
  780.  
  781.     printf("%s\n", modHelp);
  782.  
  783.     var = GetVar(item, CLASSID);
  784.     if (var && GetInt(var) == CLASS_MENU)
  785.     {
  786.         if (!GetPredicate(item, HALTAUTODOC))
  787.         {
  788.         SpitOutMenu(item, level + 1);
  789.         }
  790.     }
  791.     }
  792. }
  793.  
  794. #ifdef PROTO
  795. void EmitMenuDoc(void)
  796. #else
  797. void EmitMenuDoc()
  798. #endif
  799. /*Automatically emits documentation for all menu items to standard output.
  800.   Wow!
  801. */
  802. {
  803.     SpitOutMenu(mainMenu, 0);
  804. }
  805.  
  806. #ifdef PROTO
  807. ObjPtr FindMenuItem(ObjPtr menu, char *actionName)
  808. #else
  809. ObjPtr FindMenuItem(menu, actionName)
  810. ObjPtr menu;
  811. char *actionName;
  812. #endif
  813. /*Finds a menu item in menu named actionName*/
  814. {
  815.     ObjPtr var;
  816.     ObjPtr *items;
  817.     ObjPtr action;
  818.     int k;
  819.  
  820.     MakeVar(menu, NAME);
  821.     var = GetVar(menu, NAME);
  822.     if (var)
  823.     {
  824.     if (0 == strcmp2(actionName, GetString(var)))
  825.     {
  826.         return menu;
  827.     }
  828.     }
  829.  
  830.     var = GetVar(menu, ITEMS);
  831.     if (var)
  832.     {
  833.     items = ELEMENTS(var);
  834.     for (k = 0; k < DIMS(var)[0]; ++k)
  835.     {
  836.         action = FindMenuItem(items[k], actionName);
  837.         if (action) return action;
  838.     }
  839.     }
  840.     return NULLOBJ;
  841. }
  842.  
  843. #ifdef PROTO
  844. void DefineFunctionKey(int key, int flags, char *actionName)
  845. #else
  846. void DefineFunctionKey(key, flags, actionName)
  847. int key;
  848. int flags;
  849. char *actionName;
  850. #endif
  851. /*Defines a function key given from key and flags to do an action located 
  852.  using actionName.  Only F_SHIFTDOWN and F_ALTDOWN are used*/
  853. {
  854.     int modFlags;
  855.     ObjPtr action;
  856.  
  857.     modFlags = flags & 3;
  858.  
  859.     action = FindMenuItem(mainMenu, actionName);
  860.     if (!action)
  861.     {
  862.     action = FindMenuItem(hiddenMenu, actionName);
  863.     if (!action)
  864.     {
  865.         char outStr[100];
  866.         sprintf(outStr, "Action %s is not found\n", actionName);
  867.         ReportError("DefineFunctionKey", outStr);
  868.         return;
  869.     }
  870.     }
  871.  
  872.     if (keyActions[key][flags])
  873.     {
  874.     /*Clean up the old one*/
  875.     SetVar(keyActions[key][flags], FUNCTIONKEY, NULLOBJ);
  876.     SetVar(keyActions[key][flags], FUNCTIONFLAGS, NULLOBJ);    
  877.     }
  878.  
  879.     SetVar(action, FUNCTIONKEY, NewInt(key));
  880.     SetVar(action, FUNCTIONFLAGS, NewInt(modFlags));
  881.     keyActions[key][flags] = action;
  882. }
  883.  
  884. #ifdef PROTO
  885. Bool DoFunctionKey(int key, int flags)
  886. #else
  887. Bool DoFunctionKey(key, flags)
  888. int key;
  889. int flags;
  890. #endif
  891. /*Does a function key and returns true, or else returns false*/
  892. {
  893.     ObjPtr action;
  894.  
  895.     flags &= 3;
  896.  
  897.     action = keyActions[key][flags];
  898.     if (action)
  899.     {
  900.     FuncTyp method;
  901.     method = GetMethod(action, ACTIONMETHOD);
  902.     if (method)
  903.     {
  904.         (*method)(action);
  905.         return true;
  906.     }
  907.     }
  908.     return false;
  909. }
  910.  
  911. #ifdef PROTO
  912. void InitMenus(void)
  913. #else
  914. void InitMenus()
  915. #endif
  916. /*Initializes the menu system*/
  917. {
  918.     ObjPtr action;
  919.     int k;
  920.  
  921.     /*Zero key actions*/
  922.     for (k = 0; k < MAX_KEYS; ++k)
  923.     {
  924.     keyActions[k][0] = NULLOBJ;
  925.     keyActions[k][1] = NULLOBJ;
  926.     keyActions[k][2] = NULLOBJ;
  927.     keyActions[k][3] = NULLOBJ;
  928.     }
  929.  
  930.     /*Set up classes*/
  931.     menuClass = NewObject(NULLOBJ, 0L);
  932.     AddToReferenceList(menuClass);
  933.     SetVar(menuClass, CLASSID, NewInt(CLASS_MENU));
  934.     SetVar(menuClass, ACTIVATED, ObjTrue);
  935. #ifdef MENUS4D
  936.     DeclareDependency(menuClass, MENUSTRUCTURE, ITEMS);
  937.     SetMethod(menuClass, MENUSTRUCTURE, MakeGLMenuStructure);
  938.     SetMethod(menuClass, CLEANUP, CleanupGLMenuStructure);
  939. #endif
  940.     SetVar(menuClass, TYPESTRING, NewString("menu"));
  941.  
  942.     actionClass = NewObject(NULLOBJ, 0L);
  943.     AddToReferenceList(actionClass);
  944.     SetVar(actionClass, ACTIVATED, ObjTrue);
  945.     SetVar(actionClass, CLASSID, NewInt(CLASS_ACTION));
  946.     SetVar(actionClass, TYPESTRING, NewString("menu item"));
  947.  
  948.     /*Build the hidden menu*/
  949.     hiddenMenu = NewMenu("Function Keys");
  950.     AddToReferenceList(hiddenMenu);
  951.     SetVar(hiddenMenu, HELPSTRING,
  952.     NewString("This menu contains items only available through function keys."));
  953.  
  954.     /*Build the file menu*/
  955.     fileMenu = NewMenu("File");
  956.     SetVar(fileMenu, HELPSTRING,
  957.     NewString("This menu contains items for working with disk files."));
  958.  
  959.     /*Build the datasets menu*/
  960.     datasetsMenu = NewMenu("Dataset");
  961.     SetVar(datasetsMenu, HELPSTRING,
  962.     NewString("This menu contains items for working with datasets."));
  963.  
  964.     /*Build the object menu*/
  965.     objectMenu = NewMenu("Object");
  966.     SetVar(objectMenu, HELPSTRING,
  967.     NewString("This menu contains items for working with miscellaneous objects."));
  968.  
  969.     /*Build the arrange menu*/
  970.     arrangeMenu = NewMenu("Arrange");
  971.     AddMenuItem(objectMenu, arrangeMenu, 0);
  972.     SetVar(arrangeMenu, HELPSTRING,
  973.     NewString("This menu contains items for arranging 2-D drawing objects on space panels."));
  974.  
  975.     /*Build the network menu*/
  976.     networkMenu = NewMenu("Network");
  977.     SetVar(networkMenu, HELPSTRING,
  978.     NewString("This menu contains items for connecting to other copies of SciAn over the network."));
  979.  
  980.     /*Build the deus menu*/
  981.     deusMenu = NewMenu("Deus");
  982.     SetVar(deusMenu, HELPSTRING,
  983.     NewString("This menu contains items for the development of SciAn."));
  984.  
  985.     /*Build the text menu*/
  986.     textMenu = NewMenu("Text");
  987.     SetVar(textMenu, HELPSTRING,
  988.     NewString("This menu contains items for working with text."));
  989.  
  990.     /*Build the window menu*/
  991.     windowMenu = NewMenu("Window");
  992.     DeclareDependency(windowMenu, MENUSTRUCTURE, MOUSEWINDOW);
  993.     SetVar(windowMenu, HELPSTRING,
  994.     NewString("This menu contains items for working with windows."));
  995.  
  996.     /*Build the location menu*/
  997.     locationMenu = NewMenu("Window Location");
  998.     AddMenuItem(windowMenu, locationMenu, 0);
  999.     SetVar(locationMenu, HELPSTRING,
  1000.     NewString("This menu contains items for setting the location and size of windows."));
  1001.  
  1002.     /*Build the tile menu*/
  1003.     tileMenu = NewMenu("Window Tiling");
  1004.     AddMenuItem(windowMenu, tileMenu, 0);
  1005.     SetVar(tileMenu, HELPSTRING,
  1006.     NewString("This menu contains items for tiling all the visualization windows on the screen."));
  1007.  
  1008.     /*Build the animation menu*/
  1009.     animationMenu = NewMenu("Animation");
  1010.     SetVar(animationMenu, HELPSTRING,
  1011.     NewString("This menu contains items for working with animation."));
  1012.  
  1013.     /*Build the color menu*/
  1014.     colorMenu = NewMenu("Color");
  1015.     SetVar(colorMenu, HELPSTRING,
  1016.     NewString("This menu contains items for editing color palettes within their control panels."));
  1017.  
  1018.     /*Build the color model menu*/
  1019.     colorModelMenu = NewMenu("Color Model");
  1020.     AddMenuItem(colorMenu, colorModelMenu, 2);
  1021.     SetVar(colorModelMenu, HELPSTRING,
  1022.     NewString("This menu contains items for setting the color model used when editing a color palette.  \
  1023. SciAn currently supports four color models: RGB (Red Green Blue), YIQ (NTSC color encoding), \
  1024. HSV (Hue Saturation Value), and HLS (Hue Lightness Saturation)."));
  1025.  
  1026.     /*Build the font menu*/
  1027.     fontMenu = NewMenu("Text Font");
  1028.     DeclareDependency(fontMenu, ACTIVATED, ALLSELECTED);
  1029.     SetMethod(fontMenu, ACTIVATED, MakeFontActivated);
  1030.     SetVar(fontMenu, ACTIVATED, ObjFalse);
  1031.     SetVar(fontMenu, HALTAUTODOC, ObjTrue);
  1032.     AddMenuItem(textMenu, fontMenu, 2);
  1033.     SetVar(fontMenu, HELPSTRING,
  1034.     NewString("This menu contains a variety of text fonts.  Select a group of \
  1035. text objects and choose a font to change all the text to that font."));
  1036.  
  1037.     /*Build the size menu*/
  1038.     fontSizeMenu = NewMenu("Text Size");
  1039.     DeclareDependency(fontSizeMenu, ACTIVATED, ALLSELECTED);
  1040.     SetMethod(fontSizeMenu, ACTIVATED, MakeFontSizeActivated);
  1041.     SetVar(fontSizeMenu, ACTIVATED, ObjFalse);
  1042.     SetVar(fontSizeMenu, HALTAUTODOC, ObjTrue);
  1043.     AddMenuItem(textMenu, fontSizeMenu, 2);
  1044.     SetVar(fontSizeMenu, HELPSTRING,
  1045.     NewString("This menu contains a variety of text point sizes.  Select a group of \
  1046. text objects and choose a text size to change all the text to that size."));
  1047.  
  1048.     /*Build the align menu*/
  1049.     alignMenu = NewMenu("Text Alignment");
  1050.     AddMenuItem(textMenu, alignMenu, 2);
  1051.     SetVar(alignMenu, HELPSTRING,
  1052.     NewString("This menu contains three ways to align text with its borders."));
  1053.  
  1054.     /*Build the main menu*/
  1055.     mainMenu = NewMenu("SciAn");
  1056.     AddToReferenceList(mainMenu);
  1057.     DeclareDependency(mainMenu, MENUSTRUCTURE, MOUSEWINDOW);
  1058.     SetVar(mainMenu, HASTITLE, ObjTrue);
  1059.     AddMenuItem(mainMenu, fileMenu, 1);
  1060. #ifndef RELEASE
  1061.     AddMenuItem(mainMenu, networkMenu, 1);
  1062. #endif
  1063.     AddMenuItem(mainMenu, datasetsMenu, 1);
  1064.     AddMenuItem(mainMenu, objectMenu, 1);
  1065.     AddMenuItem(mainMenu, colorMenu, 1);
  1066. #ifdef GODLIKE
  1067.     AddMenuItem(mainMenu, deusMenu, 1);
  1068. #endif
  1069.     AddMenuItem(mainMenu, textMenu, 1);
  1070.     AddMenuItem(mainMenu, windowMenu, 1);
  1071.     AddMenuItem(mainMenu, animationMenu, 1);
  1072. }
  1073.  
  1074. #ifdef PROTO
  1075. void KillMenus(void)
  1076. #else
  1077. void KillMenus()
  1078. #endif
  1079. /*Kills the menu system*/
  1080. {
  1081.     RemoveFromReferenceList(mainMenu);
  1082.     RemoveFromReferenceList(hiddenMenu);
  1083.     RemoveFromReferenceList(menuClass);
  1084.     RemoveFromReferenceList(actionClass);
  1085.     SAFEFREE(storedActions);
  1086. }
  1087.